package com.edu.quartz.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.edu.quartz.config.NicezhuanyeConfig;
import com.edu.quartz.domain.nicezhuangye.SchedulerInfo;
import com.edu.quartz.domain.nicezhuangye.SchedulerInfo.TeacherInfo;
import com.edu.quartz.domain.nicezhuangye.StudentInfo;
import com.edu.quartz.domain.nicezhuangye.StudentInfo.StudentEntry;
import com.edu.quartz.service.ISyncSchoolTimetableService;
import com.edu.quartz.service.NicezhuanyeFactory;
import com.edu.system.domain.StudentClassExt;
import com.edu.system.domain.TClass;
import com.edu.system.domain.TClassExt;
import com.edu.system.domain.TLessonTimetable;
import com.edu.system.domain.TTeacher;
import com.edu.system.domain.TTeacherExt;
import com.edu.system.service.ITClassExtService;
import com.edu.system.service.ITLessonTimetableService;
import com.edu.system.service.ITTeacherExtService;
import com.edu.system.service.StudentClassExtService;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author huangc
 *
 */
@Slf4j
@Service
public class SyncSchoolTimetableServiceImpl implements ISyncSchoolTimetableService {

	@Resource
	private NicezhuanyeConfig nicezhuanyeConfig;
	@Resource
	private NicezhuanyeFactory nicezhuanyeFactory;
	@Resource
	private ITTeacherExtService itTeacherExtService;
	@Resource
	private ITClassExtService itClassExtService;
	@Resource
	private ITLessonTimetableService itLessonTimetableService;
	@Resource
	private StudentClassExtService studentClassExtService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void syncTimetable() {

		log.info("拉本周课表 开始");
		SchedulerInfo schedulerInfo = doPost(new HashMap<>(), nicezhuanyeConfig.getSchedule(), SchedulerInfo.class);
		if (schedulerInfo == null || CollectionUtils.isEmpty(schedulerInfo.getSchedule())) {
			log.info("拉本周课表 无数据：{}", JSONObject.toJSONString(schedulerInfo));
			return;
		}
		this.handleScheduleData(schedulerInfo);

		log.info("拉下周课表 开始");
		SchedulerInfo schedulerInfo2 = doPost(new HashMap<>(), nicezhuanyeConfig.getNextSchedule(), SchedulerInfo.class);
		if (schedulerInfo2 == null || CollectionUtils.isEmpty(schedulerInfo2.getSchedule())) {
			log.info("拉下周课表 无数据：{}", JSONObject.toJSONString(schedulerInfo2));
			return;
		}
		this.handleScheduleData(schedulerInfo2);

		// 拉学生班级关系
		this.pullStudentInfo();
	}

	private void handleScheduleData(SchedulerInfo schedulerInfo) {
		// 课表
		List<TLessonTimetable> tables = schedulerInfo.getSchedule()
				.stream()
				.map(a -> {
					TLessonTimetable timetable = new TLessonTimetable();
					timetable.setLessonName(a.getSubjectName());
					timetable.setLessonDate(DateUtil.parseDate(a.getDate()));
					timetable.setStartTime(a.getBeginTime());
					timetable.setEndTime(a.getEndTime());
					timetable.setClassCode(a.getQualifiedClassID());
					timetable.setClassName(a.getClassFullName());
					timetable.setLocationId(a.getLocationID());
					timetable.setLocationName(a.getLocationName());
					// 老师
					List<TeacherInfo> teachers = a.getTeachers();
					TTeacherExt teacherExt = Optional.ofNullable(teachers)
							.filter(CollectionUtils::isNotEmpty)
							.map(t -> t.get(0))
							.map(t -> itTeacherExtService.checkAndSaveByCode(
									TTeacherExt.builder().eid(t.getTeacherEID()).name(t.getTeacherName()).build())
							).orElseGet(TTeacherExt::new);
					timetable.setTeacherEid(teacherExt.getEid());
					timetable.setTeacherName(teacherExt.getName());
					return timetable;
				}).collect(Collectors.toList());

		// 新建课表
		tables.forEach(a ->{
			TLessonTimetable t = new TLessonTimetable();
			t.setLessonDate(a.getLessonDate());
			t.setClassCode(a.getClassCode());
			t.setStartTime(a.getStartTime());
			List<TLessonTimetable> exist = itLessonTimetableService.selectTLessonTimetableList(t);
			if (CollectionUtils.isEmpty(exist)){
				log.info("新建课表:{}", JSONObject.toJSONString(a));
				itLessonTimetableService.insertTLessonTimetable(a);
			} else {
				// 更新
				t.setId(exist.get(0).getId());
				itLessonTimetableService.updateTLessonTimetable(t);
			}
		});
	}


	private void pullStudentInfo(){

		Date d = new Date();
		log.info("拉学生基本信息 开始");
		StudentInfo info = doPost(new HashMap<>(), nicezhuanyeConfig.getStudentInfo(), StudentInfo.class);
		if (info == null || CollectionUtils.isEmpty(info.getStudentInfos())) {
			log.info("拉学生基本信息 无数据：{}", JSONObject.toJSONString(info));
			return;
		}

		List<StudentClassExt> insertData = new ArrayList<>();
		for (StudentEntry se : info.getStudentInfos()){
			StudentClassExt curData = StudentClassExt.builder()
					.name(se.getStudentName())
					.eid(se.getStudentEID())
					.qualifiedClass(se.getQualifiedClassID())
					.teachingClass(String.join(",", se.getTeachingClassFullIDs()))
					.electiveClass(String.join(",", se.getElectiveClassFullIDs()))
					.build();

			StudentClassExt oldData = studentClassExtService.selectByEid(se.getStudentEID());
			if (Objects.isNull(oldData)){
				insertData.add(curData);
			} else {
				// 有变化则更新
				if (curData != oldData){
					curData.setId(oldData.getId());
					studentClassExtService.updateById(curData);
				}
			}
		}

		if (CollectionUtils.isNotEmpty(insertData)){
			studentClassExtService.batchInsert(insertData);
		}
		Date e = new Date();
		log.info("拉学生基本信息 结束; 耗时：{}秒", (e.getTime() - d.getTime()) / 1000);

	}


	private <T> T doPost(Map<String, String> body, String url, Class<T> cls) {

		// 公用参数
		body.put("appKey", nicezhuanyeConfig.getAppKey());
		body.put("schoolID", nicezhuanyeConfig.getSchoolId());
		RequestBody body1 = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
				JSONObject.toJSONString(body));

		Request request = new Request.Builder()
				.url(url)
				.post(body1)
				.build();

		try {
			Response response = nicezhuanyeFactory.niceHttpClient().newCall(request).execute();

			if (response.isSuccessful()) {
				String resp = response.body().string();
				JSONObject jsonObject = JSON.parseObject(resp);
				log.info("请求智慧校园 返回：{}" , resp);
				if ("success".equals(jsonObject.get("status"))) {
					JSONObject result = jsonObject.getJSONObject("result");
					if (null != result) {
						return JSONObject.parseObject(String.valueOf(result), cls);
					}
				}
			}
		} catch (Exception e){
			log.error("请求智慧校园 异常：{}", e.getMessage(), e);
		}

		return null;
	}


}
